#ifndef __GLF_TASK_TASK_DECL_H_INCLUDED__
#define __GLF_TASK_TASK_DECL_H_INCLUDED__

#include <glf/core/inlines.h>
#include <glf/core/syncEvent.h>

namespace glf {

namespace task_detail {

class Runnable
{
public:
	inline virtual ~Runnable();
	virtual void Run() = 0;
};

template <typename F>
class TRunnable : public Runnable
{
public:
	explicit TRunnable(const F& func);
	virtual void Run();

protected:

	F Functor;
};

class Group;

} // end namespace task_detail

class Task : NonCopyable
{
public:
	explicit Task(bool manage = true);
	template <typename F> explicit Task(const F& f, bool manage = true);
	virtual ~Task();

	template<typename Tag>
	void Push(bool signal = true);

	void MyRun();
	virtual void Run();

	int Wait(unsigned int time = 0);

	inline bool IsManaged() const;

	void* operator new (size_t);
	void operator delete(void*);

protected:

	enum TaskState
	{
		NONE,
		WAIT_IN_PROGRESS,
		WAIT,
		DONE_IN_PROGRESS,
		DONE
	};

protected:

	SyncEvent m_DoneEvent;
	volatile unsigned long m_DoneState;
	bool m_IsManaged;

	task_detail::Runnable* m_Runnable;
	task_detail::Group* m_TaskGroup;

	void Done();
};

} // end namespace glf

#endif // __GLF_TASK_TASK_DECL_H_INCLUDED__
